﻿namespace LearnDSHashing;

public class LinkedListForHash
{
    private Node head;
    private Node tail;
    private int size;

    public LinkedListForHash()
    {
        head = null;
        tail = null;
        size = 0;
    }

    public int Length()
    {
        return size;
    }

    public bool IsEmpty()
    {
        return size == 0;
    }

    public void AddLast(int e)
    {
        Node newest = new Node(e, null);
        if (IsEmpty())
            head = newest;
        else
        {
            tail.next = newest;
        }

        tail = newest;
        size++;
    }

    public void AddFirt(int e)
    {
        Node newest = new Node(e, null);
        if (IsEmpty())
        {
            head = newest;
            tail = newest;
        }
        else
        {
            newest.next = head;
            head = newest;
        }

        size++;
    }

    public void AddAny(int e, int position)
    {
        if (position <= 0 || position >= size)
        {
            Console.WriteLine("Invalid Position");
            return;
        }

        Node newest = new Node(e, null);
        Node p = head;
        int i = 1;
        while (i < position - 1)
        {
            p = p.next;
            i++;
        }

        newest.next = p.next;
        p.next = newest;
        size++;
    }

    public int RemoveFirst()
    {
        if (IsEmpty())
        {
            Console.WriteLine("LinkedList is empty");
            return -1;
        }
        else
        {
            int e = head.element;
            head = head.next;
            size--;
            if (IsEmpty())
                tail = null;
            return e;
        }
    }

    public int RemoveLast()
    {
        if (IsEmpty())
        {
            Console.WriteLine("LinkedList is empty");
            return -1;
        }
        else
        {
            Node p = head;
            int i = 1;
            while (i < size - 1)
            {
                p = p.next;
                i++;
            }

            tail = p;
            p = p.next;
            int e = p.element;
            tail.next = null;
            size--;
            return e;
        }
    }

    public int RemoveAny(int position)
    {
        if (position <= 0 || position >= size - 1)
        {
            Console.WriteLine("Invalid Position");
            return -1;
        }

        Node p = head;
        int i = 1;
        while (i < position - 1)
        {
            p = p.next;
            i++;
        }

        int e = p.next.element;
        p.next = p.next.next;
        size = size - 1;
        return e;
    }

    public int Search(int key)
    {
        Node p = head;
        int index = 0;
        while (p != null)
        {
            if (p.element == key)
                return index;
            p = p.next;
            index++;
        }

        return -1;
    }

    public void InsertSorted(int e)
    {
        Node newest = new Node(e, null);
        if (IsEmpty())
            head = newest;
        else
        {
            Node p = head;
            Node q = head;
            while (p != null && p.element < e)
            {
                q = p;
                p = p.next;
            }

            if (p == head)
            {
                newest.next = head;
                head = newest;
            }
            else
            {
                newest.next = q.next;
                q.next = newest;
            }
        }

        size++;
    }

    public void Display()
    {
        Node p = head;
        while (p != null)
        {
            Console.Write(p.element + " ");
            p = p.next;
        }

        Console.WriteLine();
    }
}